package {
	import com.greensock.TweenMax;
	
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	
	import net.eriksjodin.arduino.Arduino;
	import net.eriksjodin.arduino.events.ArduinoEvent;
	
	import nl.alwinzwets.controllers.Glas;
	import nl.alwinzwets.controllers.SoundEffect;
	import nl.alwinzwets.visuals.Infoscreen;
	import nl.alwinzwets.visuals.Onderzoeksresultaten;
	
	[SWF(width="1920", height="1080", frameRate="30", backgroundColor="0xFFFFFF")]
 
	public class GV extends Sprite
	{
		private var _glas:Glas;
		private var a:Arduino;
		private var _glasArray:Array;
		private var _pinArray:Array;
		private var _assignArray:Array;
		private var _currentMethod:String;

		private var _dnaSound:SoundEffect;		
		private var _bloemSound:SoundEffect;		
		private var _bladSound:SoundEffect;		
		
		public static var eigenStengel:int;
		public static var eigenBlad:int;
		public static var eigenBloem:int;
		public static var eigenMeeldraad:int;
		public static var eigenStamper:int;
		
		public var dnaOnderzocht:int = 0;
		public var bladOnderzocht:int = 0;
		public var bloemOnderzocht:int = 0;
		
		public var info:Infoscreen;
		public var resultaten:Onderzoeksresultaten;
		
		public function GV()
		{
			setupArduino();
			loadSoundEffects();
			plaatsInfoScreen();
			plaatsPlanten();
			assignPlantenToPins();
			plaatsOnderzoeksresultaten();
			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyEvent);
		}
		
		//** SoundEffects
		//---------------------------------------------------------------------------
		private function loadSoundEffects():void
		{
			_dnaSound = new SoundEffect("../sounds/dna_long.mp3");
			_bloemSound = new SoundEffect("../sounds/bloem.mp3");
			_bladSound = new SoundEffect("../sounds/blad.mp3");
			
		}
		
		//** Infoscherm
		//---------------------------------------------------------------------------
		private function plaatsInfoScreen():void
		{
			_currentMethod = "home";
			info = new Infoscreen();
			addChild(info);
			info.x = stage.stageWidth - 400;
			info.y = stage.stageHeight - 100;
			
			info.addEventListener(Event.ENTER_FRAME, onInfoEnterFrame);	
		}
		
		//** Onderzoeksresultaten
		//---------------------------------------------------------------------------
		private function plaatsOnderzoeksresultaten():void
		{
			
			resultaten = new Onderzoeksresultaten();
			addChild(resultaten);
			
			resultaten.x = stage.stageWidth - 650;
			resultaten.y = stage.stageHeight - 400;
			resultaten.visible = false;
			
			info.addEventListener(Event.ENTER_FRAME, onInfoEnterFrame);	
		}
		
		private function onderzoekAfgerond():void
		{
			TweenMax.to(info, .5, {alpha:0, onComplete:onFinishTween, onCompleteParams:[info]});
			
			for(var l:int = 0; l < _glasArray.length; l++){
				
				TweenMax.to(_glasArray[l], .5, {alpha:0, onComplete:onFinishTween, onCompleteParams:[_glasArray[l]]});

				function onFinishTween(mc:Object):void {
					mc.visible = false;
					if(l == _glasArray.length){
						resultaten.alpha = 0;
						resultaten.visible = true;
						TweenMax.to(resultaten, .5, {alpha:1, onComplete:showOutcome});
					}
				}

			}
			
			function showOutcome():void
			{
				var max:int = Math.max(bladOnderzocht, bloemOnderzocht, dnaOnderzocht);
				var pct = ((bladOnderzocht * max) / 240);
				
				trace("Blad: " + bladOnderzocht);
				trace("Bloem: " + bloemOnderzocht);
				trace("DNA: " + dnaOnderzocht);	
			}
		}
		
		//** Planten 
		//---------------------------------------------------------------------------
		
		
		private function plaatsPlanten():void
		{
			
			eigenStengel = (Math.round(Math.random()*5)+1);;
			eigenBlad = (Math.round(Math.random()*18)+1);
			eigenBloem = (Math.round(Math.random()*17)+1);
			eigenMeeldraad = (Math.round(Math.random()*9)+1);
			eigenStamper = (Math.round(Math.random()*5)+1);
			
			_glasArray = new Array();
			
			var x:int = 0;
			var r:int = 0;
			for(var i:int = 0; i < 10; i++){
				if(x == 5){
					x = 0;
					r++;
				}
				_glas = new Glas((Math.round(Math.random()*5)+1),(Math.round(Math.random()*18)+1),(Math.round(Math.random()*17)+1),(Math.round(Math.random()*9)+1),(Math.round(Math.random()*5)+1),0);
				_glas.x = 250 + (x * 350);
				_glas.y = 150 + (r * 350);
				_glas.addEventListener(MouseEvent.CLICK, onGlasClick);
				addChild(_glas);
				_glasArray.push(_glas);
				x++;
			}
			
			_glas = new Glas(eigenStengel,eigenBlad,eigenBloem,eigenMeeldraad,eigenStamper,1);
			_glas.x = 250 + (2 * 350);
			_glas.y = 150 + (2 * 350);
			_glas.addEventListener(MouseEvent.CLICK, onGlasClick);
			addChild(_glas);
			_glasArray.push(_glas);
			
		}
		
		private function onInfoEnterFrame(e:Event):void
		{
			if(info.currentFrame == 9 || info.currentFrame == 40 || info.currentFrame == 72 || info.currentFrame == 97){
				info.stop();
			}
		}
		
		private function onGlasClick(e:Event):void{
			var mcPlant:Object = e.currentTarget;
			if(mcPlant.owner == 1){
				onderzoekAfgerond();
				return;
			}
			trace(mcPlant);
			if(mcPlant.faded == 1){
				TweenMax.to(mcPlant, .5, {colorTransform:{tint:0xFFFFFF, tintAmount:0}});
				TweenMax.to(mcPlant, .5,  {colorMatrixFilter:{saturation:1}});
				mcPlant.faded = 0;
			} else {
				TweenMax.to(mcPlant, .5, {colorTransform:{tint:0xFFFFFF, tintAmount:0.5}});
				TweenMax.to(mcPlant, .5,  {colorMatrixFilter:{saturation:0}});
				mcPlant.faded = 1;
			}
		}
		
		private function digitalSwitch(obj:Object):void{
			var mcPlant:Object = obj;
			if(mcPlant.faded == 1){
				TweenMax.to(mcPlant, .5, {colorTransform:{tint:0xFFFFFF, tintAmount:0}});
				TweenMax.to(mcPlant, .5,  {colorMatrixFilter:{saturation:1}});
				mcPlant.faded = 0;
			} else {
				TweenMax.to(mcPlant, .5, {colorTransform:{tint:0xFFFFFF, tintAmount:0.5}});
				TweenMax.to(mcPlant, .5,  {colorMatrixFilter:{saturation:0}});
				mcPlant.faded = 1;
			}
		}
		
		private function assignPlantenToPins():void
		{
			_pinArray = new Array();
			for(var i:int = 13; i > 0; i--){
				var _date:Date = new Date();
				
				if(_pinArray.length == 0){
					_pinArray.push(new Array(12, 1, _date.time));
				} else {
					_pinArray.push(new Array((_pinArray.length+1), 1, _date.time));
				}
				
			}
		}
		
		private function keyEvent(e:KeyboardEvent):void
		{
			switch(e.keyCode){
				case 68:
					if(_currentMethod != "dna"){
						dnaOnderzocht++;
						info.gotoAndPlay("dna");
						_dnaSound.play();
						for(var i:int = 0; i < _glasArray.length; i++){
							_glasArray[i].setMethod("DNA");
						}
						_currentMethod = "dna";
					}
					break;
				case 66:
					if(_currentMethod != "bloemen"){
						bloemOnderzocht++;
						info.gotoAndPlay("bloemen");
						_bloemSound.play();
						for(var j:int = 0; j < _glasArray.length; j++){
							_glasArray[j].setMethod("Bloem");
						}
						_currentMethod = "bloemen";
					}
					break;
				case 76:
					if(_currentMethod != "bladvorm"){
						bladOnderzocht++;
						info.gotoAndPlay("bladvorm");
						_bladSound.play();
						for(var k:int = 0; k < _glasArray.length; k++){
							_glasArray[k].setMethod("Blad");
						}
						_currentMethod = "bladvorm";
					}
					break;
				case 82:
				if(_currentMethod != "home"){
					info.gotoAndPlay("home");
					for(var l:int = 0; l < _glasArray.length; l++){
						_glasArray[l].setMethod("Reset");
					}
					_currentMethod = "home";
				}
					break;
				case 78:
					for(var m:int = 0; m < 2; m++){
						removeChild(_glasArray[m]);
						_glasArray[m] = null;
					}	
						plaatsPlanten();
					break;
				case 39:
					info.play();
					break;
				
				
			}
		}
		
		//** Arduino 
		//---------------------------------------------------------------------------
		
		private function setupArduino():void
		{
			a = new Arduino("127.0.0.1", 5331);
			a.addEventListener(Event.CONNECT,onSocketConnect);
			a.addEventListener(ArduinoEvent.FIRMWARE_VERSION, onReceiveFirmwareVersion);
			a.addEventListener(ArduinoEvent.DIGITAL_DATA, onReceiveDigitalData);
		}
		
		private function onReceiveFirmwareVersion(e:ArduinoEvent):void {
			trace("Firmware version: " + e.value);
			if(int(e.value)!=2) {
				trace("Unexpected Firmware version encountered! This Version of as3glue was written for Firmata2.");
			}
			trace("Port: " + e.port);
					
			arduinoConnections();
		}
		
		private function arduinoConnections():void
		{
			a.setPinMode(13, Arduino.INPUT);
			a.enableDigitalPinReporting();
		}
		
		private function onReceiveDigitalData(e:ArduinoEvent):void {
			
			var key:int = in_array(e.pin, _pinArray);
			var _date:Date = new Date();
			if(_pinArray[key][2] < (_date.time+1000)){
				if(e.value == 0 && _pinArray[key][1] == 1){
					digitalSwitch(_glasArray[key]);
					_pinArray[key][1] = 3;
					_pinArray[key][2] = _date.time;
				} else if(e.value == 0 && _pinArray[key][1] == 0) {
					digitalSwitch(_glasArray[key]);
					_pinArray[key][1] = 1;
					_pinArray[key][2] = _date.time;
				}
			}
				if(e.value == 1 && _pinArray[key][1] == 3) {
					_pinArray[key][1] = 0;
				}
			
			trace("Digital pin " + e.pin + " on port: " + e.port +" = " + e.value);
		}
					
		private function onSocketConnect(e:Object):void {
			a.requestFirmwareVersion();
			trace("Requesting firmware version...");	
		}
		
		//** General 
		//---------------------------------------------------------------------------
		private function in_array(needle:int, haystack:Array)
		{
			for(var i:int = 0; i < haystack.length; i++)
			{
				if(haystack[i][0] == needle){
					return i;
				}
			}
			return false;
		}
		
	}
}
